home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Parser / pgenmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  3.7 KB  |  210 lines

  1. /* Parser generator main program */
  2.  
  3. /* This expects a filename containing the grammar as argv[1] (UNIX)
  4.    or asks the console for such a file name (THINK C).
  5.    It writes its output on two files in the current directory:
  6.    - "graminit.c" gets the grammar as a bunch of initialized data
  7.    - "graminit.h" gets the grammar's non-terminals as #defines.
  8.    Error messages and status info during the generation process are
  9.    written to stdout, or sometimes to stderr. */
  10.  
  11. /* XXX TO DO:
  12.    - check for duplicate definitions of names (instead of fatal err)
  13. */
  14.  
  15. #include "pgenheaders.h"
  16. #include "grammar.h"
  17. #include "node.h"
  18. #include "parsetok.h"
  19. #include "pgen.h"
  20.  
  21. int Py_DebugFlag;
  22. int Py_VerboseFlag;
  23.  
  24. /* Forward */
  25. grammar *getgrammar Py_PROTO((char *filename));
  26. #ifdef THINK_C
  27. int main Py_PROTO((int, char **));
  28. char *askfile Py_PROTO((void));
  29. #endif
  30.  
  31. void
  32. Py_Exit(sts)
  33.     int sts;
  34. {
  35.     exit(sts);
  36. }
  37.  
  38. int
  39. main(argc, argv)
  40.     int argc;
  41.     char **argv;
  42. {
  43.     grammar *g;
  44.     FILE *fp;
  45.     char *filename;
  46.     
  47. #ifdef THINK_C
  48.     filename = askfile();
  49. #else
  50.     if (argc != 2) {
  51.         fprintf(stderr, "usage: %s grammar\n", argv[0]);
  52.         Py_Exit(2);
  53.     }
  54.     filename = argv[1];
  55. #endif
  56.     g = getgrammar(filename);
  57.     fp = fopen("graminit.c", "w");
  58.     if (fp == NULL) {
  59.         perror("graminit.c");
  60.         Py_Exit(1);
  61.     }
  62.     printf("Writing graminit.c ...\n");
  63.     printgrammar(g, fp);
  64.     fclose(fp);
  65.     fp = fopen("graminit.h", "w");
  66.     if (fp == NULL) {
  67.         perror("graminit.h");
  68.         Py_Exit(1);
  69.     }
  70.     printf("Writing graminit.h ...\n");
  71.     printnonterminals(g, fp);
  72.     fclose(fp);
  73.     Py_Exit(0);
  74.     return 0; /* Make gcc -Wall happy */
  75. }
  76.  
  77. grammar *
  78. getgrammar(filename)
  79.     char *filename;
  80. {
  81.     FILE *fp;
  82.     node *n;
  83.     grammar *g0, *g;
  84.     perrdetail err;
  85.     
  86.     fp = fopen(filename, "r");
  87.     if (fp == NULL) {
  88.         perror(filename);
  89.         Py_Exit(1);
  90.     }
  91.     g0 = meta_grammar();
  92.     n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
  93.               (char *)NULL, (char *)NULL, &err);
  94.     fclose(fp);
  95.     if (n == NULL) {
  96.         fprintf(stderr, "Parsing error %d, line %d.\n",
  97.             err.error, err.lineno);
  98.         if (err.text != NULL) {
  99.             int i;
  100.             fprintf(stderr, "%s", err.text);
  101.             i = strlen(err.text);
  102.             if (i == 0 || err.text[i-1] != '\n')
  103.                 fprintf(stderr, "\n");
  104.             for (i = 0; i < err.offset; i++) {
  105.                 if (err.text[i] == '\t')
  106.                     putc('\t', stderr);
  107.                 else
  108.                     putc(' ', stderr);
  109.             }
  110.             fprintf(stderr, "^\n");
  111.             PyMem_DEL(err.text);
  112.         }
  113.         Py_Exit(1);
  114.     }
  115.     g = pgen(n);
  116.     if (g == NULL) {
  117.         printf("Bad grammar.\n");
  118.         Py_Exit(1);
  119.     }
  120.     return g;
  121. }
  122.  
  123. #ifdef THINK_C
  124. char *
  125. askfile()
  126. {
  127.     char buf[256];
  128.     static char name[256];
  129.     printf("Input file name: ");
  130.     if (fgets(buf, sizeof buf, stdin) == NULL) {
  131.         printf("EOF\n");
  132.         Py_Exit(1);
  133.     }
  134.     /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
  135.     if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
  136.         printf("No file\n");
  137.         Py_Exit(1);
  138.     }
  139.     return name;
  140. }
  141. #endif
  142.  
  143. void
  144. Py_FatalError(msg)
  145.     char *msg;
  146. {
  147.     fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
  148.     Py_Exit(1);
  149. }
  150.  
  151. #ifdef macintosh
  152. /* ARGSUSED */
  153. int
  154. guesstabsize(path)
  155.     char *path;
  156. {
  157.     return 4;
  158. }
  159. #endif
  160.  
  161. /* No-nonsense my_readline() for tokenizer.c */
  162.  
  163. char *
  164. PyOS_Readline(prompt)
  165.     char *prompt;
  166. {
  167.     int n = 1000;
  168.     char *p = PyMem_MALLOC(n);
  169.     char *q;
  170.     if (p == NULL)
  171.         return NULL;
  172.     fprintf(stderr, "%s", prompt);
  173.     q = fgets(p, n, stdin);
  174.     if (q == NULL) {
  175.         *p = '\0';
  176.         return p;
  177.     }
  178.     n = strlen(p);
  179.     if (n > 0 && p[n-1] != '\n')
  180.         p[n-1] = '\n';
  181.     return PyMem_REALLOC(p, n+1);
  182. }
  183.  
  184. #ifdef HAVE_STDARG_PROTOTYPES
  185. #include <stdarg.h>
  186. #else
  187. #include <varargs.h>
  188. #endif
  189.  
  190. void
  191. #ifdef HAVE_STDARG_PROTOTYPES
  192. PySys_WriteStderr(const char *format, ...)
  193. #else
  194. PySys_WriteStderr(va_alist)
  195.     va_dcl
  196. #endif
  197. {
  198.     va_list va;
  199.  
  200. #ifdef HAVE_STDARG_PROTOTYPES
  201.     va_start(va, format);
  202. #else
  203.     char *format;
  204.     va_start(va);
  205.     format = va_arg(va, char *);
  206. #endif
  207.     vfprintf(stderr, format, va);
  208.     va_end(va);
  209. }
  210.